#include "pch/std_cmath.h"
#include "vector.h"

using namespace BaseGeo;

Vector::Vector(const Point& from, const Point& to) :
    Coordinate(to.x - from.x, to.y - from.y) {}


Vector::Vector(const double x, const double y) : Coordinate(x, y) {}


Vector Vector::operator-() const 
{
    return Vector(- x, - y);
}


Vector Vector::operator+(const Vector& other) const
{
    return Vector(x + other.x, y + other.y);
}


Vector Vector::operator-(const Vector& other) const
{
    return Vector(x - other.x, y - other.y);
}


Vector Vector::operator*(const Vector& other) const
{
    return Vector(x * other.x, y * other.y);
}


Vector Vector::operator*(const double x) const
{
    return Vector(this->x * x, this->y * x);
}


Vector& Vector::operator+=(const Vector& other)
{
    this->x += other.x;
    this->y += other.y;

    return *this;
}


Vector& Vector::operator-=(const Vector& other)
{
    this->x -= other.x;
    this->y -= other.y;

    return *this;
}


Vector& Vector::operator*=(const Vector& other)
{
    this->x /= other.x;
    this->y /= other.y;

    return *this;
}


Vector& Vector::operator*=(const double x)
{
    this->x *= x;
    this->y *= y;

    return *this;
}


double Vector::Length() const
{
    return std::sqrt(x * x + y * y);
}


double Vector::AngleWith(const Vector& other) const
{
    double dot_product = DotMult(*this, other);
    return std::acos(dot_product / (this->Length() * other.Length()));
}


double BaseGeo::CrossMult(const Vector& vector_x, const Vector &vector_y)
{
    return vector_x.x * vector_y.y - vector_x.y * vector_y.x;
}


double BaseGeo::DotMult(const BaseGeo::Vector& vector_x, const Vector& vector_y)
{
    return vector_x.x * vector_y.x + vector_x.y * vector_y.y;
}


std::ostream& operator<<(std::ostream& stream, const BaseGeo::Vector& Vector)
{
    stream << "(" << Vector.x << ", " << Vector.y << ")";

    return stream;
}